
import { Provide, Inject } from '@midwayjs/core';
import { StudentDao } from '@dao/student.dao';
import { createStudentUserDto, UpdateStudentDto, QueryStudentDto } from '@dto/student.dto';
import { DownloadExcelService } from '../service/common/downloadExcel';
import { ImportExcelDTO } from '@dto/common/excel.dto';
import { ResolveExcelService } from "@service/common/resolveWebExcel";
import { GradeDao } from "@dao/grade.dao";
@Provide()
export class StudentService {
  @Inject()
  studentDao: StudentDao;
  @Inject()
  downloadExcelService: DownloadExcelService;
  @Inject()
  resolveExcelService: ResolveExcelService;
  @Inject()
  gradeDao: GradeDao;

   // 创建
  async create(body: createStudentUserDto) {
    return await this.studentDao.create(body);
  }

  // 获取列表
  async list(query: QueryStudentDto) {
    return await this.studentDao.list(query);
  }
  // 获取详情
  async detail(studentId: string) {
    return await this.studentDao.detail(+studentId);
  }
  // 修改
  async update( body: UpdateStudentDto) {
    return await this.studentDao.update(body);
  }
  // 删除
  async remove(studentIds: Array<number>) {
    return await this.studentDao.remove(studentIds);
  }
  // 导出
  async export(queryParams: QueryStudentDto) {
    const headers = [
      { label: '学生ID', prop: 'studentId' },
      { label: '用户ID', prop: 'userId' },
      { label: '学号', prop: 'stuId' },
      { label: '邮箱', prop: 'email' },
      { label: '个人简介', prop: 'summary' },
      { label: '年级ID', prop: 'gradeId' },
      { label: '专业ID', prop: 'majorId' },
      { label: '备注', prop: 'remark' },
      { label: '状态（0正常 1停用）', prop: 'status' }
    ];
    const { rows } = (await this.studentDao.list(queryParams)).data;
    return this.downloadExcelService.downloadExcel({
      headers,
      data: rows,
      sheetName: 'Student信息',
    });
  }
  // 导入模板
  async importTemplate() {
    return await this.downloadExcelService.downloadExcel({
      headers: [
        { label: '学号', prop: 'stuId' },
        { label: '姓名', prop: 'nickName' },
        { label: '邮箱', prop: 'email' },
        { label: '个人简介', prop: 'summary' },
        { label: '学院（如：生物医学工程学院）', prop: 'dept' },
        { label: '年级（如：2023级）', prop: 'grade' },
        { label: '专业（如：信息管理与信息系统）', prop: 'major' },
      ],
      data: [],
      sheetName: 'Student模板',
    });
  }
  // 导入数据
  async importData(body: ImportExcelDTO) {
    const { files, updateSupport } = body;

    // 1.解析Excel文件
    const result = await this.resolveExcelService.resolvedWebExcelStream(files);
    const { tableData } = result;

    if (!tableData || tableData.length === 0) {
      throw new Error('导入数据为空');
    }

    // 2.获取学院-年级-专业树形结构
    const treeResult = await this.gradeDao.tree();
    const treeData = treeResult.data;

    // 3.构建查找Map，提高查询效率
    const lookupMaps = this.buildLookupMaps(treeData);

    // 4.转换Excel数据为实体对象
    const students = [];
    const errors = [];

    for (let i = 0; i < tableData.length; i++) {
      try {
        const row = tableData[i];
        // Excel列: [学号, 姓名, 邮箱, 个人简介, 学院, 年级, 专业]
        const [stuId, nickName, email, summary, deptName, gradeName, majorName] = row;

        // 验证必填字段
        if (!stuId) {
          errors.push(`第${i + 2}行：学号不能为空`);
          continue;
        }
        if (!nickName) {
          errors.push(`第${i + 2}行：姓名不能为空`);
          continue;
        }

        // 查找学院ID
        const dept = lookupMaps.deptMap.get(deptName?.trim());
        if (!dept) {
          errors.push(`第${i + 2}行：学院"${deptName}"不存在`);
          continue;
        }

        // 查找年级ID（必须属于该学院）
        const gradeKey = `${dept.deptId}_${gradeName?.trim()}`;
        const grade = lookupMaps.gradeMap.get(gradeKey);
        if (!grade) {
          errors.push(`第${i + 2}行：学院"${deptName}"下不存在年级"${gradeName}"`);
          continue;
        }

        // 查找专业ID（必须属于该年级）
        const majorKey = `${grade.gradeId}_${majorName?.trim()}`;
        const major = lookupMaps.majorMap.get(majorKey);
        if (!major) {
          errors.push(`第${i + 2}行：年级"${gradeName}"下不存在专业"${majorName}"`);
          continue;
        }

        // 构建学生数据对象
        students.push({
          stuId: String(stuId).trim(),
          nickName: String(nickName).trim(),
          email: email ? String(email).trim() : '',
          summary: summary ? String(summary).trim() : '',
          deptId: dept.deptId,
          gradeId: grade.gradeId,
          majorId: major.majorId,
          status: '0',
        });
      } catch (error) {
        errors.push(`第${i + 2}行：数据解析失败 - ${error.message}`);
      }
    }

    // 5.如果有错误，返回错误信息
    if (errors.length > 0) {
      throw new Error(`导入失败，共${errors.length}条错误：\n${errors.join('\n')}`);
    }

    // 6.批量导入数据（使用事务）
    const results = await this.studentDao.batchImport(students, updateSupport);

    return {
      success: true,
      message: `导入完成！成功${results.successCount}条，失败${results.failCount}条`,
      data: results,
    };
  }

  /**
   * 构建查找Map，提高查询效率
   * @param treeData 学院-年级-专业树形数据
   */
  private buildLookupMaps(treeData: any[]) {
    // 学院Map: deptName -> { deptId, deptName }
    const deptMap = new Map();
    // 年级Map: "deptId_gradeName" -> { gradeId, gradeName, deptId }
    const gradeMap = new Map();
    // 专业Map: "gradeId_majorName" -> { majorId, majorName, gradeId }
    const majorMap = new Map();

    for (const dept of treeData) {
      // 添加学院
      deptMap.set(dept.deptName, {
        deptId: dept.deptId,
        deptName: dept.deptName,
      });

      // 遍历年级
      if (dept.children && dept.children.length > 0) {
        for (const grade of dept.children) {
          const gradeKey = `${dept.deptId}_${grade.gradeName}`;
          gradeMap.set(gradeKey, {
            gradeId: grade.gradeId,
            gradeName: grade.gradeName,
            deptId: grade.deptId,
          });
          // 遍历专业
          if (grade.children && grade.children.length > 0) {
            for (const major of grade.children) {
              const majorKey = `${grade.gradeId}_${major.majorName}`;
              majorMap.set(majorKey, {
                majorId: major.majorId,
                majorName: major.majorName,
                gradeId: major.gradeId,
              });
            }
          }
        }
      }
    }

    return { deptMap, gradeMap, majorMap };
  }
}
